<template>
  <div class="upload-excel">
    <div class="btn-upload">
      <el-button :loading="loading" type="primary" @click="handleUpload">
        点击上传
      </el-button>
    </div>

    <input
      ref="excelUploadInput"
      class="excel-upload-input"
      type="file"
      accept=".xlsx, .xls, .csv"
      @change="handleChange"
    />
    <!-- https://developer.mozilla.org/zh-CN/docs/Web/API/HTML_Drag_and_Drop_API -->
    <div
      class="drop"
      @drop.stop.prevent="handleDrop"
      @dragover.stop.prevent="handleDragover"
      @dragenter.stop.prevent="handleDragover"
    >
      <!-- <i class="el-icon-upload" /> -->
      <svg-icon icon="plugin-upload" style="font-size: 40px" />
      <span>将excel文件拖拽到此处</span>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import XLSX from 'xlsx'
import { ElMessage, ElMessageBox } from 'element-plus'
import { getHeaderRow, isExcel } from '@/utils/excel.utils'

const loading = ref(false)
const excelUploadInput = ref(null)

// 上传之前的回调 beforeUpload
// 上传成功的回调 onSuccess

// 点击上传触发
const handleUpload = () => {
  excelUploadInput.value.click()
}
const handleChange = (e) => {
  const files = e.target.files
  const rawFile = files[0]
  if (!rawFile) return
  upload(rawFile)
}
// 处理上传事件
const upload = (rawFile) => {
  excelUploadInput.value.value = null
  // 如果需要上传前操作的话，可以在此处 todo
  // 读取数据
  readerData(rawFile)
}

// 读取异步数据
const readerData = (rawFile) => {
  loading.value = true
  return new Promise((resolve) => {
    const reader = new FileReader()
    reader.onload = (e) => {
      // 1. 获取到解析后的数据
      const data = e.target.result
      // 2. 利用xlsx对数据进行解析
      const workbook = XLSX.read(data, { type: 'array' })
      // 3. 获取第一张表格(工作簿)名称
      const firstSheetName = workbook.SheetNames[0]
      // 4. 读取sheet1数据
      const workSheet = workbook.Sheets[firstSheetName]
      // 5. 解析数据表头
      const headerRow = getHeaderRow(workSheet)
      // 6. 解析数据内容
      const results = XLSX.utils.sheet_to_json(workSheet)
      // 7. 传入解析之后的数据
      generateData({ headerRow, results })
      // 8. 处理loading
      loading.value = false
      // 9. 成功回调
      resolve(data)
    }
    reader.readAsArrayBuffer(rawFile)
  })
}

// 解析excel转换成的json数据
const generateData = (data) => {
  ElMessageBox.alert(
    `<div>表头：${JSON.stringify(data.headerRow)}</div>
    <div>表内容：${JSON.stringify(data.results)}</div>
    `,
    '获取到excel数据',
    {
      dangerouslyUseHTMLString: true
    }
  )
}

// 拖拽上传
/**
 *     drop：当元素或选中的文本在可释放目标上被释放时触发
 * drogover：当元素或选中的文本被拖放到一个可释放目标上时触发
 * dragenter：当拖拽元素或选中的文本到一个可释放目标上时触发
 */
const handleDrop = (e) => {
  // 1. 上传中不可操作
  if (loading.value) return
  // 2. 判断是否有上传文件
  const files = e.dataTransfer.files
  if (files.length !== 1) {
    ElMessage.error('必须有一个文件')
    return
  }
  // 3. 判断上传的文件是不是excel
  const newFile = files[0]
  if (!isExcel(newFile)) {
    ElMessage.error('文件必须是 .xlsx, .xls, .csv 格式')
    return
  }
  // 4. 上传
  upload(newFile)
}
// 拖拽进入到指定区域
const handleDragover = (e) => (e.dataTransfer.dropEffect = 'copy')
</script>

<style lang="scss" scoped>
.upload-excel {
  width: 730px;
  margin: 0 auto;
  display: flex;
  justify-content: space-between;
  margin-top: 100px;
  .excel-upload-input {
    display: none;
    z-index: -9999;
  }
  .btn-upload,
  .drop {
    border: 1px dashed #bbb;
    width: 350px;
    height: 160px;
    text-align: center;
    line-height: 160px;
  }
  .drop {
    line-height: 60px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    color: #bbb;
    i {
      font-size: 60px;
      display: block;
    }
    span {
      line-height: 30px;
    }
  }
}
</style>
